import { Icon } from "@/components/icon";
// import type { ColumnsType } from 'antd/es/table';
import { ScrollArea } from "@/ui/scroll-area";
import ProTable from "@/components/ProTable/Index";
import type { GetRef, TableProps } from "antd";
import { Button, Form, Input, Popconfirm, InputNumber } from "antd";
import React, { useState, useContext, useEffect } from "react";

// 表格数据类型
interface DataType {
	key: string;
	name: string;
	age: string;
	address: string;
}

type ColumnTypes = Exclude<TableProps<DataType>["columns"], undefined>;

type FormInstance<T> = GetRef<typeof Form<T>>;

const EditableContext = React.createContext<FormInstance<any> | null>(null);

interface EditableRowProps {
	index: number;
}

interface Item {
	key: string;
	name: string;
	age: string;
	address: string;
}

const EditableRow: React.FC<EditableRowProps> = ({ index, ...props }) => {
	const [form] = Form.useForm();
	return (
		<Form form={form} component={false}>
			<EditableContext.Provider value={form}>
				<tr {...props} />
			</EditableContext.Provider>
		</Form>
	);
};

interface EditableCellProps {
	title: React.ReactNode;
	editable: boolean;
	dataIndex: keyof Item;
	record: Item;
	handleSave: (record: Item) => void;
}

// 可编辑单元格
const EditableCell: React.FC<React.PropsWithChildren<EditableCellProps>> = ({
	title,
	editable,
	children,
	dataIndex,
	record,
	handleSave,
	...restProps
}) => {
	const [editing, setEditing] = useState(false);

	const form = useContext(EditableContext)!;

	// 切换编辑状态
	const toggleEdit = () => {
		setEditing(!editing);
		form.setFieldsValue({ [dataIndex]: record[dataIndex] });
	};

	// 保存
	const save = async () => {
		try {
			const values = await form.validateFields();

			toggleEdit();
			handleSave({ ...record, ...values });
		} catch (errInfo) {
			console.log("Save failed:", errInfo);
		}
	};

	let childNode = children;

	if (editable) {
		childNode = editing ? (
			// 编辑状态
			<Form.Item style={{ margin: 0 }} name={dataIndex} rules={[{ required: true, message: `${title} is required.` }]}>
				{dataIndex === "name" ? (
					<Input onPressEnter={save} onBlur={save} />
				) : (
					<InputNumber onPressEnter={save} onBlur={save} />
				)}
			</Form.Item>
		) : (
			// 非编辑状态
			<div className="editable-cell-value-wrap" style={{ paddingInlineEnd: 24 }} onClick={toggleEdit}>
				{children}
			</div>
		);
	}

	return <td {...restProps}>{childNode}</td>;
};

// 表格页面
const TableEditPage = () => {
	// 表格列配置
	const columns: (ColumnTypes[number] & { editable?: boolean; dataIndex: string })[] = [
		{
			title: "name",
			dataIndex: "name",
			key: "name",
			editable: true,
		},
		{
			title: "age",
			dataIndex: "age",
			key: "age",
			editable: true,
		},
		{
			title: "地址",
			key: "address",
			dataIndex: "address",
		},
		{
			title: "Action",
			key: "action",
			width: 180,
			fixed: "right",
			dataIndex: "action",
			render: (_, record) => (
				<div>
					<Popconfirm title="Sure to delete?" onConfirm={() => handleDelete(record.key)}>
						<Button color="danger" variant="outlined" size="small">
							<Icon icon="mdi:delete" />
							删除
						</Button>
					</Popconfirm>
				</div>
			),
		},
	];

	// 删除行
	const handleDelete = (key: React.Key) => {
		const newData = dataSource.filter((item) => item.key !== key);
		setDataSource(newData);
	};

	const [count, setCount] = useState(2);
	const [dataSource, setDataSource] = useState<DataType[]>([]);
	const [outLoading, setOutLoading] = useState(false);

	// 模拟接口请求，在useEffect, 在useEffect中请求接口，并设置状态，不然会有副作用
	useEffect(() => {
		setOutLoading(true);
		const timer = setTimeout(() => {
			setDataSource([
				{
					key: "0",
					name: "Edward King 0",
					age: "32",
					address: "London, Park Lane no. 0",
				},
				{
					key: "1",
					name: "Edward King 1",
					age: "32",
					address: "London, Park Lane no. 1",
				},
			]);
			setOutLoading(false);
		}, 2000);
		return () => clearTimeout(timer);
	}, []);

	// 新增行
	const addRow = () => {
		setDataSource([
			...dataSource,
			{
				key: count.toString(),
				name: `李四${count}`,
				age: `${count + 10} `,
				address: `地址${count}`,
			},
		]);
		setCount(count + 1);
	};

	// 保存行
	const handleSave = (row: DataType) => {
		// 这里的dataSource是useState的闭包变量，handleSave和addRow每次执行时会捕获到它们各自作用域内的dataSource副本。
		// 如果想在handleSave中获取最新的dataSource值，可以用函数式更新写法，避免闭包问题：
		console.log("dataSource", dataSource);
		setDataSource((prevDataSource) => {
			const newData = [...prevDataSource];
			const index = newData.findIndex((item) => row.key === item.key);
			const item = newData[index];
			newData.splice(index, 1, {
				...item,
				...row,
			});
			return newData;
		});
	};

	// 表格组件
	const components = {
		body: {
			row: EditableRow,
			cell: EditableCell,
		},
	};

	// 表格列配置
	const columnsNew = columns.map((col: any) => {
		if (!col.editable) {
			return col;
		}
		return {
			...col,
			onCell: (record: DataType) => ({
				record,
				editable: col.editable,
				dataIndex: col.dataIndex,
				title: col.title,
				handleSave,
			}),
		};
	});

	// 表格头部右侧插槽
	const tableHeaderRightSlot = (
		<div className="flex gap-2">
			<Button type="primary" onClick={addRow}>
				<Icon icon="mdi:add" />
				新增
			</Button>
		</div>
	);

	return (
		<div>
			<ScrollArea>
				<ProTable<DataType>
					components={components}
					title="编辑列表"
					outLoading={outLoading}
					tableHeaderRightSlot={tableHeaderRightSlot}
					columns={columnsNew}
					dataSource={dataSource}
					isPagination={false}
					rowKey={(record) => record.key}
				/>
			</ScrollArea>
		</div>
	);
};

export default TableEditPage;
